package com.xiao.train.business.service;

import cn.hutool.core.date.DateTime;
import com.alibaba.fastjson.JSON;
import com.xiao.train.business.domain.ConfirmOrder;
import com.xiao.train.business.dto.ConfirmOrderMQDto;
import com.xiao.train.business.enums.ConfirmOrderStatusEnum;
import com.xiao.train.business.mapper.ConfirmOrderMapper;
import com.xiao.train.business.req.ConfirmOrderDoReq;
import com.xiao.train.business.req.ConfirmOrderTicketReq;
import com.xiao.train.common.context.LoginMemberContext;
import com.xiao.train.common.exception.BusinessException;
import com.xiao.train.common.exception.BusinessExceptionEnum;
import com.xiao.train.common.util.SnowUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.redisson.api.RedissonClient;
import org.slf4j.MDC;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class BeforeConfirmOrderService {

    @Resource
    SkTokenService skTokenService;

    @Autowired
    RedissonClient redissonClient;

    @Resource
    RocketMQTemplate rocketMQTemplate;

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Resource
    ConfirmOrderMapper confirmOrderMapper;

//    @GlobalTransactional //全局事务
    public Long beforeDoConfirm(ConfirmOrderDoReq req) {
        Long memberId = LoginMemberContext.getId();
        if (skTokenService.validSkToken(req.getDate(), req.getTrainCode(), memberId)) {
            log.info("校验成功");
        } else {
            log.info("校验失败");
            throw new BusinessException(BusinessExceptionEnum.CONFIRM_ORDER_LOCK_FAIL);
        }
        Date date = req.getDate();
        String trainCode = req.getTrainCode();
        String start = req.getStart();
        String end = req.getEnd();
        List<ConfirmOrderTicketReq> reqTickets = req.getTickets();
        // todo: 发送mq之前保存订单表,状态为INIT,优先保证数据准确性
        DateTime now = DateTime.now();
        ConfirmOrder confirmOrder = new ConfirmOrder();
        confirmOrder.setCreateTime(now);
        confirmOrder.setUpdateTime(now);
        confirmOrder.setId(SnowUtil.getId());
        confirmOrder.setMemberId(req.getMemberId());
        confirmOrder.setDate(date);
        confirmOrder.setTrainCode(trainCode);
        confirmOrder.setStart(start);
        confirmOrder.setEnd(end);
        confirmOrder.setDailyTrainTicketId(req.getDailyTrainTicketId());
        confirmOrder.setStatus(ConfirmOrderStatusEnum.INIT.getCode());
        confirmOrder.setTickets(JSON.toJSONString(reqTickets));
        log.info("订单会员id:{}", confirmOrder.getMemberId());
        confirmOrderMapper.insert(confirmOrder);
        //发送mq
        ConfirmOrderMQDto dto = new ConfirmOrderMQDto();
        dto.setLogId(MDC.get("LOG_ID"));
        dto.setDate(req.getDate());
        dto.setTrainCode(req.getTrainCode());
        log.info("排队购票,发送mq开始,消息{}", dto);
//        String dtoJson = JSON.toJSONString(dto);
//        rocketMQTemplate.convertAndSend(RocketMQTopicEnum.CONFIRM_ORDER.getCode(), dtoJson);
        rabbitTemplate.convertAndSend("confirmOrder", dto);
        log.info("排队购票,发送mq结束");
        return confirmOrder.getId();
    }
}
